package com.ssm.common.utils;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

/**
 * https://blog.csdn.net/f641385712/article/details/105185361
 * https://blog.csdn.net/f641385712/article/details/105233229
 */
public class NetworkUtil {
    /**
     * 获取本机 IP 地址，即使开了 vpn 也可以
     */
    public static InetAddress getLocalHostExactAddress() {
        try {
            InetAddress candidateAddress = null;
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface iface = networkInterfaces.nextElement();
                // 该网卡接口下的 ip 会有多个，也需要一个个的遍历，找到自己所需要的
                for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {
                    InetAddress inetAddr = inetAddrs.nextElement();
                    // 排除 loopback 回环类型地址（不管是 IPv4 还是 IPv6，只要是回环地址都会返回 true）
                    if (!inetAddr.isLoopbackAddress()) {
                        if (inetAddr.isSiteLocalAddress()) {
                            // 如果是 site-local 地址，就是它了，就是我们要找的
                            // 绝大部分情况下都会在此处返回本地的 ip 地址值
                            return inetAddr;
                        }

                        // 若不是 site-local 地址，那就记录下该地址当作候选
                        if (candidateAddress == null) {
                            candidateAddress = inetAddr;
                        }
                    }
                }
            }
            // 如果出去 loopback 回环地之外无其它地址了，那就回退到原始方案
            return candidateAddress == null ? InetAddress.getLocalHost() : candidateAddress;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void setDNS() {
        // 自己指定 DNS 地址，形如这样
        // 这么一来我们的 hostName 域名都将交给`114.114.114.114`去帮我们完成解析
        System.setProperty("sun.net.spi.nameservice.nameservers", "114.114.114.114");

        // 自己指定DNS服务的提供者
        // 若你没指定此 key，那就是 default。默认就会使用系统自带的 DNS
        // `dns,sun`的意思是：会使用`sun.net.spi.nameservice.nameservers`配置指定的 DNS 来解析
        System.setProperty("sun.net.spi.nameservice.provider.1", "dns,sun");
    }
}
